package com.ktdaddy.manager;

import com.github.pagehelper.PageHelper;
import com.ktdaddy.Constants;
import com.ktdaddy.enums.WhaleErrorCode;
import com.ktdaddy.exception.BusinessRuntimeException;
import com.ktdaddy.mapper.KernelMapper;
import com.ktdaddy.mapper.KernelRoleRelMapper;
import com.ktdaddy.mapper.RoleMapper;
import com.ktdaddy.mapper.UserCustomMapper;
import com.ktdaddy.mapper.UserMapper;
import com.ktdaddy.pojo.Kernel;
import com.ktdaddy.pojo.KernelRoleRel;
import com.ktdaddy.pojo.Role;
import com.ktdaddy.pojo.User;
import com.ktdaddy.request.UserQueryReq;
import com.ktdaddy.request.UserReq;
import com.ktdaddy.utils.PageResult;
import com.ktdaddy.utils.ShiroUtils;
import com.ktdaddy.vo.UserVO;
import org.n3r.idworker.Sid;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * @author kdaddy@163.com
 * @date 2021/7/15 22:17
 */
@Component
public class UserManager extends BaseManager{

    @Resource
    private UserMapper userMapper;

    @Resource
    private KernelMapper kernelMapper;

    @Resource
    private RoleMapper roleMapper;

    @Autowired
    private Sid sid;

    @Resource
    private UserCustomMapper userCustomMapper;

    @Resource
    private KernelRoleRelMapper kernelRoleRelMapper;

    /**
     * 根据核心用户名查询核心用户信息
     * @param kernelName
     * @return
     */
    public Kernel getByKernelName(String kernelName) {
        Example example = new Example(Kernel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("kernelName", kernelName);
        return kernelMapper.selectOneByExample(example);
    }

    /**
     * 保存生成核心用户信息
     * @param userBO
     * @return
     */
    public Kernel saveKernelInfo(UserReq userBO) {
        Kernel kernel = new Kernel();
        BeanUtils.copyProperties(userBO,kernel);
        kernel.setSalt(ShiroUtils.getSalt());
        kernel.setKernelCode(sid.nextShort());

        kernel.setPassword(ShiroUtils.getEncryptPassword(kernel.getSalt(),
                userBO.getPassword(),userBO.getKernelName()));
        int i = kernelMapper.insertSelective(kernel);

        if(i < 1){
            throw new BusinessRuntimeException(WhaleErrorCode.DB_INSERT_ERROR);
        }

        return kernel;
    }

    /**
     * 保存生成用户基础信息
     * @param userBO
     * @param kernelId
     * @return
     */
    public User saveUserInfo(UserReq userBO, Integer kernelId) {
        User user = new User();
        BeanUtils.copyProperties(userBO,user);
        user.setKernelId(kernelId);
        int result = userMapper.insertSelective(user);

        if(result < 1){
            throw new BusinessRuntimeException(WhaleErrorCode.DB_INSERT_ERROR);
        }
        return user;
    }

    /**
     * 根据关键用户信息ID查询用户信息
     * @param kernelId
     * @return
     */
    public User getByKernelId(int kernelId) {
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("kernelId", kernelId);
        return userMapper.selectOneByExample(example);
    }

    /**
     * 分页查询用户信息
     * @param deptQueryReq
     * @return
     */
    public PageResult getUserListByPage(UserQueryReq deptQueryReq) {
        PageHelper.startPage(deptQueryReq.getPage(), deptQueryReq.getPageSize());
        Map<String, Object> param = new HashMap<>();
        param.put("deptId",deptQueryReq.getDeptId());
        param.put("kernelName",deptQueryReq.getKernelName());
        param.put("nickname",deptQueryReq.getNickname());
        List<UserVO> result = userCustomMapper.queryUser(param);
        return setterPagedGrid(result, deptQueryReq.getPage());
    }

    /**
     * 创建用户信息
     * @param userReq
     * @return
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public Kernel createUser(UserReq userReq) {
        //保存关键用户信息
        userReq.setPassword(Constants.INIT_PASSWORD);
        Kernel kernel = this.saveKernelInfo(userReq);
        //保存用户信息
        saveUserInfo(userReq,kernel.getId());
        //保存用户角色信息
        saveKernelRoleInfo(kernel,userReq.getRoleCode());
        return kernel;
    }

    /**
     * 保存用户角色权限
     * @param kernel
     * @param roleCode
     */
    private void saveKernelRoleInfo(Kernel kernel, String roleCode) {
        KernelRoleRel kernelRoleRel = new KernelRoleRel();
        kernelRoleRel.setKernelId(kernel.getId());
        //查询角色信息
        Example example = new Example(Role.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("roleCode",roleCode);
        Role role = roleMapper.selectOneByExample(example);
        if(Objects.isNull(role)){
           throw new BusinessRuntimeException(WhaleErrorCode.ROLE_NOT_EXIST);
        }
        kernelRoleRel.setRoleCode(roleCode);
        kernelRoleRel.setRoleId(role.getId());
        kernelRoleRel.setKernelName(kernel.getKernelName());
        kernelRoleRel.setKernelId(kernel.getId());
        Integer result = kernelRoleRelMapper.insertSelective(kernelRoleRel);
        if(result < 1){
            throw new BusinessRuntimeException(WhaleErrorCode.DB_INSERT_ERROR);
        }
    }

    public User getUserById(Integer id) {
        return userMapper.selectByPrimaryKey(id);
    }

    public Kernel getKernelById(Integer kernelId) {
        return kernelMapper.selectByPrimaryKey(kernelId);
    }

    public Kernel getKernelByMobile(String mobile) {
        Example example = new Example(Kernel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("mobile", mobile);
        return kernelMapper.selectOneByExample(example);
    }

    public Kernel getKernelByEmail(String email) {
        Example example = new Example(Kernel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("email", email);
        return kernelMapper.selectOneByExample(example);
    }

    @Transactional(propagation = Propagation.REQUIRED)
    public Integer updateUser(Kernel oldKernel, User oldUser, UserReq userReq) {
        //更新原始用户信息
        oldUser.setDeptId(userReq.getDeptId());
        oldUser.setName(userReq.getName());
        oldUser.setNickname(userReq.getNickname());
        oldUser.setSlogan(userReq.getSlogan());
        userMapper.updateByPrimaryKey(oldUser);

        //删除老的关键角色关系信息
        Example example = new Example(KernelRoleRel.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("kernelId", oldKernel.getId());
        kernelRoleRelMapper.deleteByExample(example);

        //绑定新的角色用户信息
        saveKernelRoleInfo(oldKernel,userReq.getRoleCode());

        oldKernel.setKernelName(userReq.getKernelName());
        oldKernel.setEmail(userReq.getEmail());
        oldKernel.setMobile(userReq.getMobile());
        // 如果用户名未更新，那么则密码无需重置，否则密码会重置成123456
        if(!oldKernel.getKernelName().equals(userReq.getKernelName())){
            // 更新的时候需要重置密码
            oldKernel.setPassword(ShiroUtils.getEncryptPassword(oldKernel.getSalt(),
                    Constants.INIT_PASSWORD,
                    userReq.getKernelName()));
        }

        kernelMapper.updateByPrimaryKey(oldKernel);
        return oldKernel.getId();
    }

    public Kernel getKernelByUserId(Integer userId) {
        User user = userMapper.selectByPrimaryKey(userId);
        if(Objects.isNull(user)){
            return null;
        }
        return kernelMapper.selectByPrimaryKey(user.getKernelId());
    }

    public void updateKernel(Kernel kernel) {
        Integer result = kernelMapper.updateByPrimaryKey(kernel);
        if(result < 1){
            throw new BusinessRuntimeException(WhaleErrorCode.DB_UPDATE_ERROR);
        }
    }
}
